Obwohl das Web als leistungsstarke Schnittstelle dienen kann, Informationen innerhalb einer Firma zu verteilen (indem es die Notwendigkeit abschafft, plattformspezifische Anwendungen zu entwickeln), ist es nicht unbedingt das richtige für Ihre Firma, einen eigenen Web-Server zu unterhalten. Vielleicht sind Sie eine kleine Firma und es lohnt sich nicht, einen ganzen Computer als Web-Server zu dedizieren, oder vielleicht können Sie nicht die Zeit investieren, die notwendig ist, um einen Server aufzustellen und am Laufen zu halten.
Glücklicherweise brauchen Sie mit der Ankunft der clientseitigen Skripting-Sprachen wie JavaScript keinen eigenen Server mehr, um Server-gleiche Macht auf Ihre Intranet-Dokumente auszuüben. Andererseits kann Ihr Site auch dann, wenn Sie einen Server besitzen, dramatischen Nutzen aus der zusätzlichen Flexibilität ziehen, die JavaScript bietet.
JavaScript wurde von Netscape entwickelt und stellt die nächste Generation der Browser-Programmiersprache LiveScript dar. JavaScript gibt Ihnen Zugriff auf die inneren Vorgänge im Browser aus dem HTML-Dokument heraus.
Kurz gesagt, arbeitet JavaScript mit vier unterschiedlichen Elementen: Objekte, Eigenschaften, Methoden und Ereignisse.
Das Herz von JavaScript ist das Objektkonzept. Alle Browser-Funktionen, auf die Sie über JavaScript Zugriff haben, sind in einer Kollektion von Objekten eingekapselt. Unter den am meisten verwendeten Objekten befinden sich:
Es gibt noch einige mehr, diese sollten aber ausreichen, Ihnen zu verdeutlichen, daß so gut wie alles, was Sie auf eine Seite bringen können, auch über JavaScript erreicht werden kann.
Während die Objekte einen einfachen Zugriff auf die Browser-Elemte gewährn, sind die Eigenschaften die Datenwerte für diese Objekte. So wie JavaScript-Objekte den HTML-Tags gleichgesetzt werden können, gleichen die JavaScript-Eigenschaften den HTML-Attributen.
Es wird auf die Eigenschaften eines gegebenen Objekts zugegriffen, indem der Name, ein Punkt (.) und die gewünschte Eigenschaft des Objekts spezifiziert werden, wie hier:
document.bgColor = "blue";
was auf die Hintergrundfarbe des aktuellen Dokuments zugreift und sie auf blau setzt.
Wie jede Programmiersprache unterstützt JavaScript Funktionen oder Kollektionen von JavaScript-Anweisungen, die eine bestimmte Aufgabe erfüllen. Wenn eine Funktion mit einem Objekt assoziiert ist, wird sie Methode genannt und kann die Eigenschaften des Objekts direkt manipulieren. Eine oft benutzte Methode des document-Objekts ist write, durch welche Daten im Dokument ausgegeben werden:
document.write("<H1>Hello World!</H1>");
Sie können sowohl reinen Text ausgeben als auch HTML-Tags anlegen.
Ein Ereignis wird dann ausgelöst, wenn z. B. auf einen Hyperlink geklickt, ein Button gedrückt, Text in ein Feld eingegeben oder eine Seite geladen wird. Mit JavaScript können Sie diese Ereignisse als Auslöser benutzen, die Ihren Code ablaufen lassen, wenn sie auftreten. Weithin gebräuchliche Ereignisse sind u. a.:
Um ein bestimmtes Ereignis als Auslöser einzusetzen, geben Sie seinen Namen als ein Attribut des HTML-Objekts an, das Sie kontrollieren wollen. Der Wert des Attributs besteht dann aus Ihrem JavaScript-Code, wie hier:
<A HREF="naechsteSeite.html"
ONMOUSEOVER="window.status='Naechste Seite'">Naechste Seite</A>
Um JavaScript in ein HTML-Dokument einzubetten, wenden Sie die Tags <SCRIPT> und </SCRIPT> wie folgt an:
<SCRIPT>
hier gehoert Ihr Code hin
</SCRIPT>
Sie können Skripts an beliebigen Stellen im Dokument plazieren (entweder im <HEAD> oder im <BODY>) und Sie dürfen so viele Blocks wie benötigt innerhalb derselben Datei verwenden.
Da nicht-JavaScript-fähige Browser die <SCRIPT>-Tags ignorieren und versuchen, den Code als regulären HTML-Text zu interpretieren, ist es eine gute Angewohnheit, den Code in einem HTML-Kommentar-Tag (<!--…-->) einzuschließen:
<SCRIPT>
<!-- von hier ab wird versteckt
hier gehoert Ihr Code hin
// Ende des Versteckens -->
</SCRIPT>
Der JavaScript-Interpreter läßt sich vom Kommentar-Tag nicht ablenken und interpretiert den Code, während die nicht-JavaScript-fähigen Browser den ganzen Block ignorieren.
Nachdem wir nun die Grundlagen erledigt haben, ist es an der Zeit, einige ernsthafte Implementationen von JavaScript zu betrachten. Zuerst sehen wir uns einige Methoden an, mit denen wir den Browser des Benutzers mit JavaScript kontrollieren können.
Wenn Sie innerhalb eines Intranets arbeiten, können Sie bestimmen, welche Browser benutzt werden. Wenn Ihr Intranet jedoch auch eine Brücke ins richtige Internet schlägt, haben Sie diese Kontrolle nicht länger und müssen sicherstellen, daß Ihre Seiten auf einer Vielfalt von Browsern betrachtet werden können, sowohl mit und ohne JavaScript. Die Angelegenheit wird zusätzlich dadurch kompliziert, daß der Netscape Navigator und der Internet Explorer unterschiedliche Stufen von JavaScript unterstützen und es Fehler erzeugt, wenn Sie versuchen, auf einem Browser Funktionen auszuführen, die nur vom anderen unterstützt werden.
Zum Glück können Sie mit JavaScript kontrollieren, auf welche Seiten die verschiedenen Browser zugreifen sollen. Das navigator-Objekt, das Informationen über den gerade benutzten Browser enthält, hat eine Eigenschaft namens appName, die den verwendeten Browser identifiziert. Listing 41.1 demonstriert ein Code-Fragment, das den Navigator und den Explorer automatisch zu verschiedenen Seiten in der Site hinführt.
Listing 41.1: Ein Ausschnitt einer JavaScript-Seite
<SCRIPT LANGUAGE="JavaScript">
<!--
if(navigator.appName.indexOf("Netscape") != -1) {
location.href = "netscape/index.html";
} else {
location.href = "microsoft/index.html";
}
// -->
</SCRIPT>
JavaScript kann sogar zu einem gewissen Grad dazu eingesetzt werden, nicht-JavaScript-fähige Browser zu kontrollieren. Erinnern Sie sich daran, daß die Browser, die JavaScript nicht unterstützen, den <SCRIPT>-Tag ignorieren und alles, was innerhalb liegt, als HTML behandeln. Nutzt man zudem einem Nebeneffekt JavaScript-fähiger Browser, funktioniert das folgende Code-Fragment genauso wie ein »<NOSCRIPT>«-Tag :
<SCRIPT LANGUAGE="JavaScript">
<!-- -->Nicht-Script-faehige Browser werden dies verarbeiten
</SCRIPT>
Während der JavaScript-Interpreter schlau genug ist, innerhalb des Kommentars nach dem Script-Code zu suchen, ignoriert er den Rest der Zeile, wenn er erst einmal das Kommentarbeendungszeichen (-->) angetroffen hat. Nicht-JavaScript-Browser fahren jedoch damit fort, alles als gültiges HTML zu verarbeiten, was sich nach dem abgeschlossenen Kommentar in der Zeile befindet.
Das bedeutet, daß Sie einen leeren Kommentar (<!-- -->) am Anfang einer Zeile innerhalb eines <SCRIPT>-Tags plazieren können und dann eine HTML-Anweisung erhalten, die von JavaScript (und deshalb dem Browser) ignoriert, jedoch von nicht-scriptfähigen Browsern dargestellt wird.
<SCRIPT LANGUAGE="JavaScript">
// Ihr JavaScript-Code gehoert hierher, fuer den Navigator und
// den Internet Explorer
</SCRIPT>
<SCRIPT LANGUAGE="JavaScript">
<!-- -->Diese Zeilen werden wie normales HTML behandelt,
<!-- -->aber<B>nur</B> nur von Browsern, die JavaScript nicht verstehen.
</SCRIPT>
Mit Plug-Ins können Sie die Funktionalität eines Browsers um Daten erweitern, für die er ursprünglich nicht entworfen wurde. So gut wie jede Art von Datendatei besitzt inzwischen ein Plug-In, mit dem Sie vom Web aus geöffnet und gelesen werden kann. Mit Plug-Ins können Sie eine Schnittstelle zu Textverarbeitungsdokumenten, Datenbankdateien oder Tabellenkalkulationen herstellen – ohne jemals den Browser verlassen zu müssen. Leider funktioniert das nur, wenn der Benutzer das notwendige Plug-In auf seinem System installiert hat.
Unter den verschiedenen Ergänzungen zu JavaScript, die seit dem Navigator 3.0 gelten, befindet sich auch das Array plugins[], das zum navigator-Objekt hinzugefügt wurde. Das plugins[]-Array enthält Informationen über alle Plug-Ins, die gegenwärtig im Browser installiert sind, einschließlich:
Dadurch kann man feststellen, ob ein bestimmtes Plug-In installiert ist, indem das Array durchsucht wird. Listing 41.2 demonstriert ein JavaScript-Code-Fragment, das eine Suche nach dem Shockwave-Plug-In ausführt.
Listing 41.2: Das Vorhandensein eines Plug-Ins feststellen
var nplug = navigator.plugins.length;
var i = 0;
while (i < nplug) {
if (navigator.plugins[i].name.indexOf(‘Shockwave’) != -1) {
shock = 1;
}
i++;
}
Da plugins[] ausschließlich im Navigator 3.0 zur Verfügung steht, muß immer noch überprüft werden, welche Version des Navigators gegenwärtig ausgeführt wird (um zu sehen, ob jemand den Navigator 2.x verwendet) oder ob eventuell ein anderer Browser verwendet wird (der Internet Explorer unterstützt diese Eigenschaft momentan nicht). Das wird leicht erreicht, indem die Eigenschaft appVersion des navigator-Objekts nach dem String 2. durchsucht wird (indem Sie den Dezimalpunkt angeben, verhindern Sie, daß 1.2, 3.2 oder eine andere Browser-Version gefunden wird, an der Sie nicht interessiert sind). Indem Sie die appName-Eigenschaft des Navigator-Objekts auf das Vorhandensein von Netscape hin überprüfen, können Sie feststellen, ob der Navigator oder der Explorer verwendet wird.
Listing 41.4 bringt das alles zusammen, und bietet Ihnen eine generische Funktion, die identifiziert, ob ein gegebenes Plug-In installiert wurde. Wenn der Navigator 3.0 abläuft, sucht es nach dem Plug-In. Wenn der Navigator 2.0 oder der Internet Explorer 3.0 ablaufen, geht es davon aus, daß das Plug-In installiert wurde. Wenn ein anderes Programm läuft, nimmt es an, daß das Plug-In nicht installiert wurde:
Listing 41.3: Ein Plug-In-Checker
<SCRIPT LANGUAGE="JavaScript">
<!-- Anfang der versteckten Script-Sektion
function isPluginInstalled(strPlugin) {
var fInstalled = false;
if((navigator.appVersion.lastIndexOf('3.') != -1) &&
(navigator.appName.indexOf('Netscape') != -1) {
var nplug = navigator.plugins.length;
var i = 0;
while (i < nplug) {
if (navigator.plugins[i].name.indexOf(strPlugin) != -1) {
fInstalled = true;
}
i++;
}
}
else
if((navigator.appVersion.lastIndexOf('2.') != -1) ||
(navigator.appName.indexOf('Microsoft') != -1) {
fInstalled = true;
}
return fInstalled;
}
// Ende der versteckten Script-Sektion -->
</SCRIPT>
Damit das funktioniert, müssen Sie den Namen des Plug-Ins kennen. Da Sie das Plug-In auf wenigstens einem Browser innerhalb Ihres Systems installiert haben werden, kann das HTML-Dokument aus Listing 41.4 verwendet werden, die installierten Plug-Ins zu identifizieren (inklusive ihrer Namen), wie in Abbildung 41.4 gezeigt wird.
Listing 41.4: Verfügbare Plug-Ins aufzeigen
<HTML>
<HEAD>
<TITLE>Installed Plug-ins</TITLE>
</HEAD>
<BODY BGCOLOR=#ffffff>
<CENTER>
<H1>Installed Plugins</H1>
<TABLE BORDER=3>
<TR>
<TH>Name</TH>
<TH>Description</TH>
</TR>
<SCRIPT LANGUAGE="JavaScript">
<!-- Hier wird das Script versteckt
if((navigator.appVersion.lastIndexOf('2.') != -1) ||
(navigator.appName.indexOf(‘Microsoft’) != -1)) {
document.write("<TR><TD COLSPAN=2 ALIGN=CENTER>" +
"Es wurden keine Plug-Ins gefunden</TD></TR>");
} else {
for(var i=0; i<navigator.plugins.length; i++) {
document.write("<TR>");
document.write("<TD>" +
navigator.plugins[i].name + "</TD>");
document.write("<TD>" +
navigator.plugins[i].description + "</TD>");
document.write("</TR>");
}
}
// end hide -->
</SCRIPT>
</TABLE>
</CENTER>
</BODY>
</HTML>
Mit dieser Information können Sie Ihre Seiten so anpassen, daß sie so sauber wie möglich dargestellt werden, egal, ob ein Plug-In installiert ist oder nicht. Listing 41.5 demonstriert ein Code-Fragment, das die Funktion isPluginInstalled() verwendet, um eine Shockwave-Datei einzubetten.
Listing 41.5: Das Vorhandensein von Shockwave testen
<!-- Hier wird eine Shockwave-Datei eingebettet -->
<SCRIPT LANGUAGE="JavaScript">
<!-- Script wird versteckt
if(isPluginInstalled('Shockwave')) {
document.write('<EMBED SRC="myshock.dcr" WIDTH=100 HEIGHT=50>');
} else {
document.write('<IMG SRC="noshock.gif" WIDTH=100 HEIGHT=50>');
}
// Ende des versteckten Scripts -->
</SCRIPT>
<NOEMBED>
<!-- hier wird ein visueller Platzhalter fuer Browser ohne EMBED geliefert -->
<IMG SRC="noshock.gif" WIDTH=100 HEIGHT=50>
</NOEMBED>
Abbildung 41.1: Wenn Sie testen wollen, ob ein Plug-In vorhanden ist, können Sie das Dokument in Listing 41.4 verwenden, um den Namen des Plug-Ins zu ermitteln.
Vergessen Sie nicht, daß der IMG-Platzhalter zweimal eingefügt werden muß: einmal für Browser, die zwar JavaScript-fähig sind, das Plug-In jedoch nicht installiert haben (oder nicht feststellen können, ob es installiert ist), und ein zweites Mal für ältere Browser, die weder EMBED noch JavaScript unterstützen.
JavaScript besitzt aus Sicherheitsgründen nicht die Zugriffsberechtigung, um Dateien auf dem Server lesen oder beschreiben zu können. Sie können jedoch Datenbanken erzeugen und sie innerhalb von JavaScript speichern, um sie lokal zu verarbeiten. Wenn Sie eine JavaScript-Datenbank erschaffen wollen, müssen Sie zuerst das Konzept benutzerdefinierter JavaScript-Objekte verstehen.
Wenn Sie Ihre eigenen Objekte anlegen wollen, müssen Sie zuerst eine Funktion schreiben, die den gleichen Namen hat wie das Objekt, das Sie definieren wollen (etwa Billboard). Im Inhaltsteil der Funktion können Sie beliebige Eigenschaften des Objekts initialisieren. Bei einer Datenbank mit Benutzernamen und E-Mail-Adressen hätte ein Adressen-Objekt zwei Eigenschaften (z. B. realname und email), so daß die Initialisierungsfunktion so aussähe, wie die aus Listing 41.6.
Listing 41.6: Ein Benutzerobjekt definieren
function Address(strRealname, strEmail) {
this.realname = strRealname;
this.email = strEmail;
return this;
}
Benutzerdefinierte Objekte können auch Methoden enthalten (Sie sind nicht auf Eigenschaften beschränkt). Wenn Sie eine Methode mit einem Objekt assoziieren wollen, definieren Sie zuerst die Funktion:
function eineNeueFunktion(…) {
...
}
dann verbinden Sie sie in der Konstruktionsfunktion mit einer Eigenschaft des Objekts:
this.eineNeueFunktion = eineNeueFunktion;
Nachdem nun die Initialisierungsfunktion definiert wurde, ist es ein leichtes, neue Address-Objekte zu erzeugen, indem der JavaScript-Operator new verwendet wird:
myAddress = new Address('Scott J. Walter', 'sjwalter@visi.com');
anotherAddress = new Address();
gültig wäre und ein Address-Objekt erzeugt, bei dem beide Eigenschaften auf null gesetzt sind. Das ist ein praktischer Trick, wenn Sie einem Objekt Raum zuteilen wollen, die Werte seiner Eigenschaften aber noch nicht kennen (die erfahren Sie vielleicht erst, wenn sie von einer anderen Funktion berechnet werden oder von einem Formular abgeholt werden).
Nachdem Ihr Objekte angelegt wurde, greifen Sie auf sie und ihre Eigenschaften in der gleichen Weise zu, in der Sie auf ein eingebautes Objekte von JavaScript zugreifen.
Ein Array ist eine exzellente Methode, mit Ihren Adressenobjekten leichter umgehen zu können. Arrays werden ähnlich wie benutzerdefinierte Objekte konstruiert: Zuerst erzeugen Sie eine Funktion, die das Array initialisiert und dann füllen Sie es mit Objekten. Eine Array-erzeugende Funktion (siehe Listing 41.7) unterscheidet sich von einer Objekt-erzeugenden Funktion dahingehend, daß sie anstelle von Eigenschaften Elemente besitzt (die durch Subscripts erreicht werden), wobei jedes Element ein unabhängiges Objekt ist. Arrays besitzen eine Eigenschaft, nämlich lenght, die die Größe des Arrays zurückgibt (die Anzahl der Elemente/Objekte).
Listing 41.7: Ein Array initialisieren
function initArray(iSize) {
this.length = iSize;
for(var i=1; i<=iSize; i++)
this[i] = null;
return this;
}
Nachdem die Funktion definiert wurde, ist es ein leichtes, das Array zu erzeugen und mit Inserenten zu belegen:
addresses = initArray(5); // 5-element array
addresses[1] = new Address(…);
…
addresses[5] = new Address(…);
myArray = new initArray(10);
myArray.length = 11;
myArray[11] = newElement;
myArray[100] = newElement;
würd,e die Elemente 11 bis 99 ebenfalls angelegt (und auf null gesetzt).
Sie können das alles anwenden, indem Sie ein einfaches »E-Telefonbuch« von Benutzern und E-Mail-Adressen aufstellen, wie es in Listing 41.8 gezeigt wird.
Listing 41.8: Ein Adreßbuch
<HTML>
<HEAD>
<TITLE>Company Email Addresses</TITLE>
<SCRIPT LANGUAGE="JavaScript">
<!-- Script verstecken
function Address(strRealname, strEmail) {
this.realname = strRealname;
this.email = strEmail;
return this;
}
function initArray(iSize) {
if (initArray.arguments.length)
this.length = iSize;
else
this.length = 0;
for(var i=1; i<=this.length; i++)
this[i] = null;
return this;
}
addresses = new initArray(4);
addresses[1] = new Address("Corporate", "corp@mycomp.com");
addresses[2] = new Address("Marketing", "mktg@mycomp.com");
addresses[3] = new Address("Sales", "sales@mycomp.com");
addresses[4] = new Address("Tech Support", "help@mycomp.com");
function PrintAddress(objAddr) {
return "<TD>" + objAddr.realname + "</TD>" +
"<TD><A HREF=\"mailto:" +
objAddr.email + "\">" +
objAddr.email + "</A></TD>";
}
// Ende des versteckten Scripts -->
</SCRIPT>
</HEAD>
<BODY BGCOLOR=#FFFFFF>
<CENTER>
<H1>Company Email Addresses</H1>
<P>
<TABLE BORDER=2>
<TR>
<TH>Name</TH>
<TH>Email</TH>
</TR>
<SCRIPT LANGUAGE="JavaScript">
<!-- Script wird versteckt
for(var i=1; i<=addresses.length; i++) {
document.write("<TR>");
document.write(PrintAddress(addresses[i]));
document.write("</TR>");
}
// Ende des versteckten Scripts -->
</SCRIPT>
</TABLE>
</BODY>
</HTML>
Wie Sie sehen können, übernimmt die Funktion PrintAddress() die eintönige Arbeit, alle notwendigen HTML-Tags auszuschreiben, um die Telefonliste zu formatieren. Obwohl das bei einer kleinen Liste nicht so sehr ins Gewicht fällt, wäre es doch umständlich (sowohl beim Formatieren als auch beim Warten), wenn Sie für ein paar Dutzend Namen (oder mehr) jeden HTML-Tag ausschreiben müßten.
Formulare sind die Mechanismen, durch die die Benutzer Informationen an den Server zurückschicken können. Mit JavaScript können Sie sowohl das Formular als auch die von ihm übermittelten Daten manipulieren.
Um aus JavaScript auf ein bestimmtes Formular zuzugreifen, verwenden Sie die forms[]-Eigenschaft des document-Objekts. Die forms[]-Eigenschaft ist ein Array, das einen Eintrag für jedes <FORM>-Element der akuellen Datei enthält, angefangen mit 0 (dem ersten Formular). Die Anzahl der Formulare innerhalb eines Dokuments wird innerhalb der length-Eigenschaft des forms[]-Arrays gespeichert.
Innerhalb eines jeden Formularobjekts werden die einzelnen Formularobjekte (<INPUT>-Tags, <SELECT>-Tags etc.) jeweils als individuelle Eigenschaften angesehen. Beispielsweise wären die beiden Textfelder des Beispielsformulars aus Listing 41.9:
Listing 41.9: Ein einfaches Formular
<FORM>
<INPUT TYPE=TEXT NAME="Realname">
<INPUT TYPE=TEXT NAME="Address">
<INPUT TYPE=SUBMIT VALUE="Send it!">
</FORM>
von JavaScript aus wie folgt zu erreichen:
document.forms[0].Realname.value
document.forms[0].Address.value
Die value-Eigenschaft jedes Textobjekts enthält den Text, den der Anwender eintippt.
document.forms[0].realname.value // kleines 'r'
document.forms[0].ADDRESS.value // alles in Großbuchstaben
Wenn Sie wissen, wie Sie auf die verschiedenen Formularelemente zugreifen können, können Sie sie wunschgemäß manipulieren.
Wenn ein Anwender auf den Submit-Button eines Formulars klickt, wird ein onSubmit-Ereignis erzeugt. Sie können diesem Ereignis Ihren eigenen JavaScript-Code anhängen, um die Daten innerhalb des Formulars vorzubearbeiten, bevor sie zur endgültigen Verarbeitung an den Server geschickt werden. Um das Formular abzufangen, bevor es zum Server geschickt wird, koppeln Sie das onSubmit-Ereignis des form-Objekts:
<FORM NAME="helpForm" METHOD=POST
ONSUBMIT="return Validate(this)" …>
an die JavaScript-Funktion Validate(), die Sie speziell geschrieben haben, um sich mit den Feldern Ihres Formulars zu beschäftigen. Der onSubmit-Handler kann einen Wert von true oder false zurückgeben, und dieser Wert bestimmt, ob das Formular tatsächlich übermittelt wird oder nicht. Wenn onSubmit den Wert true zurückgibt, geht die Formularbearbeitung weiter. Wenn der ausgegebene Wert false ist, bleibt das in dem Zustand, in dem es bei der Betätigung des Submit-Buttons war.
Indem Sie das einfache Formular aus Listing 41.9 anwenden, können Sie eine Routine ausklügeln, mit der geprüft wird, ob die Namens- und Adreßfelder tatsächlich ausgefüllt wurden. Listing 41.10 stellt eine Demonstration davon dar.
Listing 41.10: Formulardaten Validieren
<HTML>
<HEAD>
<TITLE>Validating Form Data</TITLE>
<SCRIPT LANGUAGE="JavaScript">
<!-- Script wird versteckt
function isEmpty(str) {
return (str == null || str == "");
}
function Validate(theForm) {
if(isEmpty(theForm.realname.value) ||
isEmpty(theForm.email.value)) {
alert("You must fill in all fields!");
return false;
}
return true;
}
// Ende des versteckten Scripts -->
</SCRIPT>
</HEAD>
<BODY BGCOLOR=#ffffff>
<FORM METHOD=POST ACTION="mailto:sales@mycomp.com"
ONSUBMIT="return Validate(this)">
Your name: <INPUT TYPE=TEXT NAME="realname"><BR>
Your email address: <INPUT TYPE=TEXT NAME="email"><BR>
<INPUT TYPE=SUBMIT VALUE="Send it!">
</FORM>
</BODY>
</HTML>
Das Überprüfen der Gültigkeit der Daten in JavaScript-Feldern ist ebenfalls unkompliziert. Da TEXT-Objekte Strings sind, können Sie die indexOf()-Methode anwenden, um nach dem Vorhandensein einer Zeichenfolge zu suchen. Wenn die Zeichenfolge nicht aufgefunden werden kann, gibt indexOf() eine Wert von -1 zurück, wie in Listing 41.11 gezeigt wird.
Listing 41.11: Test des E-Mail-Felds
if(theForm.email.value.indexOf("@") == -1) {
alert("\nEmail addresses are usually of the form:" +
"\n\nsomebody@someplace\n\n" +
"your’s doesn’t seem to be valid!");
}
Das abschließende Validierungsbeispiel kombiniert alle Tricks aus den vorigen Beispielen und fügt noch zusätzliche hinzu. Indem Sie bitweise vorgehen, können Sie den Anwender nicht nur darüber informieren, daß etwas nicht ausgefüllt ist, sondern auch was ausgefüllt werden soll, bevor das Formular verarbeitet werden kann.
Listing 41.12: Validierung mit angepaßten Fehlermeldungen
<HTML>
<HEAD>
<TITLE>Comments, Criticisms, Suggestions</TITLE>
<SCRIPT LANGUAGE="JavaScript">
<!-- Script wird versteckt
function initArray(size) {
this.length = size;
for(i = 1; i <= size; i++) {
this[i] = null;
}
return this;
}
msgCase = new initArray(3);
msgCase[1] = "You need to include your email address!";
msgCase[2] = "You must include your name!";
msgCase[3] = "What? A blank form?\nSorry, you need to fill it out first!";
function isEmpty(str) {
return (str == null || str == "");
}
function Validate(theForm) {
iName = isEmpty(theForm.realname.value) ? 1 : 0;
iEmail = isEmpty(theForm.email.value) ? 1 : 0;
iCase = (iName << 1) | iEmail;
if(iCase) {
alert("\n" + msgCase[iCase – 1]);
return false;
}
// Low-level verification of email address
//
if(theForm.email.value.indexOf("@") == -1) {
alert("\nEmail addresses are usually of the form:" +
"\n\nsomebody@someplace\n\n" +
"your’s doesn’t seem to be valid!");
return false;
}
return true;
}
// Ende des versteckten Scripts -->
</SCRIPT>
</HEAD>
<BODY TEXT=#000000 BGCOLOR=#FFFFFF>
<CENTER><H3>Comments, Criticisms, Suggestions</H3></CENTER>
<HR>
<FONT SIZE=-1><I>
If you have any comments, please send them in.
</I></FONT>
<FORM NAME="commentForm" METHOD=POST ONSUBMIT="return Validate(this)"
ACTION="mailto:info@mycomp.com">
<CENTER><TABLE>
<TR>
<TD>Your name</TD>
<TD><INPUT TYPE=TEXT NAME="realname" SIZE=40 VALUE=""></TD>
</TR>
<TR>
<TD>eMail address</TD>
<TD><INPUT TYPE=TEXT NAME="email" SIZE=40 VALUE=""></TD>
</TR>
</TABLE></CENTER>
Now, what’s on your mind?
<P>
<CENTER><TABLE>
<TR>
<TD ALIGN=CENTER>
<TEXTAREA TYPE=TEXT NAME="comment" WRAP COLS=60 ROWS=10></TEXTAREA>
</TD>
</TR>
</TABLE></CENTER>
Now ... <I>send ‘er my way!</I>
<P>
<CENTER><TABLE BORDER=3 CELLPADDING=1>
<TR>
<TD><INPUT TYPE=SUBMIT NAME="submit" VALUE="Submit Comment"></TD>
<TD><INPUT TYPE=RESET NAME="reset" VALUE=" Clear "></TD>
</TR>
</TABLE></CENTER>
<P>
</FORM>
</BODY>
</HTML>
Der springende Punkt des Skripts liegt in den folgenden Zeilen:
iName = isEmpty(theForm.realname.value) ? 1 : 0;
iEmail = isEmpty(theForm.email.value) ? 1 : 0;
Die Variablen iName und iEmail werden auf 1 oder 0 gesetzt, je nachdem, ob das assoziierte Feld leer ist oder nicht. Das scheint logisch verkehrt herum zu sein, und ist es auch wirklich, muß aber so sein, damit die folgende Zeile funktioniert:
iCase = (iName << 1) | iEmail;
Der Operator <<, der Werte bitweise nach links verschiebt, und der bitweise OR-Operator nehmen die Werte von iName und iEmail und konstruieren eine Nummer zwischen 0 und 3. Je nach der Nummer (iCase) wird eine unterschiedliche Mitteilung an den Anwender zurückgeschickt. Wenn z. B. das Feld mit realname leer wäre, das email-Feld jedoch nicht, wäre iName gleich 1 und iEmail gleich 0. Wenn diese Werte durch die obige Zeile geschickt würden, setzte das iCase auf 2. Wenn Sie sich msgCase[2] ansehen, werden Sie herausfinden, das dort die folgende Zeichenkette gespeichert ist:
You must include your name!
was sich auf das leere Feld bezieht. Dieser kleine Trick erleichtert einem die Arbeit sehr, wenn man es mit einer großen Anzahl leerer Felder zu tun hat. nachdem man alle möglichen Kombinationen der Leere herausbekommen hat.
Obwohl die Verifikation am Ende des Formulars durchgeführt wird (nachdem der User versucht hat, es zu übermitteln), können Sie JavaScript auch dazu benutzen, das Formular zu konfigurieren, bevor es das erste Mal dargestellt wird.
Nehmen wir z. B. an, daß Sie Online-Support anbieten und ein Formular zur Verfügung stellen wollen, durch das die Anwender ihre Probleme mitteilen können. Eines der größten Probleme, das die Support-Leute haben, ist der Mangel an Informationen, die von den Anwendern geliefert werden. Zu oft werden E-Mail-Mitteilungen geschickt, die vage »Es funktioniert nicht...«-Fragen enthalten, ohne Informationen darüber, welches Programm oder Betriebssystem verwendet wird. Indem Sie ein HTML-Formular (und JavaScript-Validierung) anwenden, können Sie sicherstellen, daß die von Ihrem Support-Personal benötigten Informationen geliefert werden.
Oftmals nützen jedoch auch die am gründlichsten durchdachten Pläne nichts – vor allem dann, wenn ein Anwender nicht versteht, was für eine Art von Information Sie brauchen (»Was für ein Computer? Es ist ein IBM...«). Mit den HTML-Steuerelementen, speziell dem Optionselement für Formularlisten, können sie eine eine Auswahl aus einer gewissen Liste erzwingen. Mit JavaScript können Sie die Anwendung des Formulars noch weiter erleichtern, indem Sie die Voreinstellungen der Auswahlfelder, Checkboxen und sogar der Textfelder konfigurieren.
Das onload-Ereignis (das mit dem document-Objekt und einem Attribut des <BODY>-Tags assoziiert ist) tritt auf, nachdem alle Teile des Dokuments geladen wurden, jedoch bevor irgendetwas abgebildet wurde. An diesem Punkt können Sie Einstellungen am Dokumente vornehmen, bevor der Anwender es zu sehen bekommt – z. B. die Standardwerte eines Formulars festlegen. Wenn wir das Formular für den Support als Beispiel benutzen, könnten Sie, wenn das Formular ein Feld für das Betriebssystem besäße, die appVersion-Eigenschaft des navigator-Objekts einsetzen, um zu identifizieren, welche Plattform verwendet wird. Bei select-Objekten (den JavaScript-Äquivalenten zum HTML-<SELECT>-Tag), gibt die selectedIndex-Eigenschaft an, welche der OPTION-Tags standardmäßig ausgewählt ist, wenn das Formular schließlich für den Anwender abgebildet wird.
Listing 41.13 ist ein Beispiel eines Support-Formulars, das zwei Felder mit Optionsschaltflächen enthält, in denen die Person, die das Formular ausfüllt, den von ihr angewendeten Browser und das Betriebssystem angibt.
Listing 41.13: Standardwerte voreinstellen
<HTML>
<HEAD>
<TITLE>Help Request</TITLE>
<SCRIPT LANGUAGE="JavaScript">
<!-- Script wird versteckt
function InitArray(size) {
this.length = size;
for(i = 1; i <= size; i++) {
this[i] = null;
}
return this;
}
function Init(theForm) {
if(navigator.appName.indexOf("Netscape") != -1) {
if(navigator.appVersion.indexOf("3.0") != -1) {
theForm.browser.selectedIndex = 5;
}
else
if(navigator.appVersion.indexOf("2.02") != -1) {
theForm.browser.selectedIndex = 4;
}
else
if(navigator.appVersion.indexOf("2.01") != -1) {
theForm.browser.selectedIndex = 3;
}
else
if(navigator.appVersion.indexOf("2.0") != -1) {
theForm.browser.selectedIndex = 2;
}
if(navigator.appVersion.indexOf("Win16") != -1) {
theForm.OS.selectedIndex = 5;
}
else
if(navigator.appVersion.indexOf("WinNT") != -1) {
theForm.OS.selectedIndex = 4;
}
else
if(navigator.appVersion.indexOf("Win95") != -1) {
theForm.OS.selectedIndex = 3;
}
else
if(navigator.appVersion.indexOf("Unix") != -1) {
theForm.OS.selectedIndex = 2;
}
else
if(navigator.appVersion.indexOf("Mac") != -1) {
theForm.OS.selectedIndex = 1;
}
}
}
msgCase = new InitArray(7);
msgCase[1] = "You need to submit a desription of your problem,\nnot just your name and address!";
msgCase[2] = "You need to include your email address!";
msgCase[3] = "You have to give me more than just your name!";
msgCase[4] = "You must include your name!";
msgCase[5] = "You have to give me more than just your email address!";
msgCase[6] = "You need to include your name and address!";
msgCase[7] = "What? A blank form?\nSorry, you need to fill it out first!";
function isEmpty(str) {
return (str == null || str == "");
}
function Validate(theForm) {
iName = isEmpty(theForm.realname.value) ? 1 : 0;
iEmail = isEmpty(theForm.email.value) ? 1 : 0;
iText = isEmpty(theForm.problem.value) ? 1 : 0;
iCase = (iName << 2) | (iEmail << 1) | iText;
if(iCase) {
alert("\n" + msgCase[iCase – 1]);
return false;
}
// Hier wird die E-Mail-Adresse auf einer unteren Ebene ueberprueft
//
if(theForm.email.value.indexOf("@") == -1) {
alert("\nEmail addresses are usually of the form:" +
"\n\nsomebody@someplace\n\n" +
"your’s doesn’t seem to be valid!");
return false;
}
if(theForm.OS.selectedIndex == 0) {
alert("\nI need to know your operating system!");
return false;
}
if(theForm.browser.selectedIndex == 0) {
alert("\nI need to know the version of your browser!");
return false;
}
return true;
}
// Ende des versteckten Scripts -->
</SCRIPT>
</HEAD>
<BODY TEXT=#000000 BGCOLOR=#FFFFFF ONLOAD="Init(document.helpForm)">
<H2>
If you need help, please complete the following form:
</H2>
<P>
<FORM NAME="helpForm" METHOD=POST ONSUBMIT="return Validate(this)"
ACTION="mailto:help@mycomp.com">
<CENTER><TABLE>
<TR>
<TD>Your name</TD>
<TD><INPUT TYPE=TEXT NAME="realname" SIZE=40 VALUE=""></TD>
</TR>
<TR>
<TD>eMail address</TD>
<TD><INPUT TYPE=TEXT NAME="email" SIZE=40 VALUE=""></TD>
</TR>
<TR>
<TD>Operating System</TD>
<TD>
<SELECT NAME="OS" WIDTH=30>
<OPTION>- please specify -
<OPTION>Macintosh (including PowerPC)
<OPTION>Unix
<OPTION>Windows 95
<OPTION>Windows NT
<OPTION>Windows 3.x
</SELECT>
</TD>
</TR>
<TR>
<TD>Browser</TD>
<TD>
<SELECT NAME="browser">
<OPTION>- please specify -
<OPTION>Internet Explorer 3.0
<OPTION>Navigator 2.0
<OPTION>Navigator 2.01
<OPTION>Navigator 2.02
<OPTION>Navigator 3.0
</SELECT>
</TR>
</TABLE></CENTER>
Please describe your problem:
<P>
<CENTER><TABLE>
<TR>
<TD ALIGN=CENTER>
<TEXTAREA TYPE=TEXT NAME="problem" WRAP COLS=60 ROWS=15></TEXTAREA>
</TD>
</TR>
</TABLE></CENTER>
<CENTER><TABLE BORDER=3 CELLPADDING=1>
<TR>
<TD><INPUT TYPE=SUBMIT NAME="submit" VALUE="Submit Problem"></TD>
<TD><INPUT TYPE=RESET NAME="reset" VALUE=" Clear "></TD>
</TR>
</TABLE></CENTER>
<P>
</FORM>
</BODY>
</HTML>
Da JavaScript sich als Sprache noch im Kleinkindstadium befindet, wird sie fortwährend aktualisiert und ausgeweitet, wodurch sie für Bücher wie das vorliegende eine Art von »beweglichem Ziel« abgibt. Mit der wachsenden Beliebtheit der Sprache gibt es jedoch eine Vielzahl von Online-Ressourcen für weitere Informationen.
Was folgt, ist ein Überblick verschiedener Web-Sites, Usenet Newsgroups und Mailing-Lists, die mehr Informationen (und Hilfe) bezüglich JavaScript bieten können. Diese Liste ist bei weitem nicht umfassend; einige der Web-Sites stellen jedoch ausgezeichnete Ausgangspunkte für weitere Nachforschungen dar.
Als die Heimat von JavaScript stellt Netscape immer die neuesten Informationen darüber zur Verfügung, was bei jedem Release vom Navigator-Browser neu oder verändert ist. Ihre Online-Autorenrichtlinien listen jedes Objekte, jede Methode und jede Eigenschaft dieser Sprache auf.
Der JavaScript-Index ist ein solides Kompendium von JavaScript-Implementationen und -Experimenten, einschließlich einer wachsenden Liste persönlicher Homepages, die eine Vielfalt von JavaScript-Tricks zur Schau stellen. Die JavaScript-Bibliothek ist eine Ecke der Site, die eine kleine, aber anwachsende Kollektion von Quellcodes von überall in der Web-Gemeinschaft anbietet.
In der wachsenden Kollektion kostenlos verfügbarer Skripts präsentiert das Cut-N-Paste JavaScript Center eine interessante Schnittstelle für den Zugang zu verschiedenen JavaScript-Tricks. Sie können nach einem Skript suchen, es in Aktion sehen, es dann ausschneiden und es in Ihre Dokumente kopieren.
Dies ist eine Kollektion von Beispielen, die fortgeschrittene Konzepte in JavaScript behandelt, einschließlich Cookies. Danny Goodman ist einer der de-facto-Experten für JavaScript auf dem Web und liefert hier einige gute Beispiele, von denen Sie lernen und Ihre eigenen Applikationen ableiten können.
Wegen der unterschiedlichen Implementierungen von Netscape Navigator und Internet Explorer (und den Unterschieden innerhalb der verschiedenen Versionen der Browser selbst) versucht dieser Site, alle Informationen darüber zu sammeln, welche Methoden, Funktionen, Eigenschaften und Objekte auf welchen Browser-Konfigurationen verfügbar sind.
Als einziger Newsgroup, die sich spezifisch der JavaScript-Entwicklung widmet, geht es in dieser manchmal ziemlich lebhaft zu.
Der JavaScript Index ist die einzige Mailing-List, die sich zum Zeitpunkt, als dies geschrieben wird, ausdrücklich JavaScript widmet. Die Liste wird von Obscure Organization ( http://www.obscure.org/ ) and TeleGlobal Media, Inc. ( http://www.tgm.com/ ) gesponsort. Die Diskussion ist ziemlich vielfältig und reicht von einführenden Fragen zu anspruchsvolleren Diskussionen darüber, wie Animation, Framing, Reloads usw. am besten zu handhaben seien. Wenn Sie abonnieren wollen, senden Sie eine Mitteilung an majordomo@obscure.org mit subscribe javascript im Inhaltsteil. Alternativ können Sie Ihren Browser auf http://www.obscure.org/javascript/ richten, um mehr Informationen zu bekommen.
(c) 1997 Que